/*
* ====================================================================
* Copyright (c) 2013-2014 Neudesic.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that redistributions of source
* retain the above copyright notice, this list of conditions and the
* following disclaimer.
*
* This source file includes software written by Neudesic, LLC (http://www.neudesic.com).
*
* THIS SOFTWARE IS PROVIDED BY Neudesic, LLC ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  FURTHER, IN NO EVENT SHALL
* Neudesic, LLC (THE AUTHOR) OR ANY CONTRIBUTORS BE LIABLE FOR ANY DAMAGES
* WHATSOEVER THAT ARE RELATED TO THE SOFTWARE [INCLUDING BUT NOT LIMITED TO,
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* SUCH AS LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION, HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)] EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGES.
*
* ====================================================================
*/
#ifndef __HANDLE_MANAGER_H__
#define __HANDLE_MANAGER_H__

#include <Windows.h>
namespace Neudesic {
	namespace Sockets {
		//This class is a simple wrapper around Win32 handles to make certain that they are closed.
		class HandleManager
		{
		public:
			HandleManager();
			HandleManager(HANDLE handle);
			~HandleManager();
			void Attach(HANDLE handle);
			HANDLE Detach();
			HANDLE Get() const;
			int Close();
		private:
			HANDLE handle;
		};

		class EventManager : public HandleManager
		{
		public:
			void Set();
			void Reset();
			int Wait(DWORD timeout) const;
			static int WaitAll(DWORD count, const HANDLE* lpHandles, BOOL bWaitAll, DWORD timeout);
		protected:
			void CreateEvent(DWORD dwFlags, LPSECURITY_ATTRIBUTES lpEventAttributes = NULL, LPCTSTR lpName = NULL);
		};

		class ManualResetEvent : public EventManager
		{
		public:
			ManualResetEvent();
			ManualResetEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCTSTR lpName);
		};

		class AutoResetEvent : public EventManager
		{
		public:
			AutoResetEvent();
			AutoResetEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCTSTR lpName);
		};
	}
}
#endif	//__HANDLE_MANAGER_H__